package com.slz.crm.server.service.impl;

import com.slz.crm.common.enumeration.ChartOperates.TimeRangeOperate;
import com.slz.crm.common.untils.DataChartUtils;
import com.slz.crm.pojo.dto.ContractChartDTO;
import com.slz.crm.pojo.dto.DataStatisticsDTO;
import com.slz.crm.server.constant.ChartTitleConstant;
import com.slz.crm.server.constant.ContractConstant;
import com.slz.crm.server.mapper.ContractMapper;
import com.slz.crm.server.service.DataStatisticsService;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DataStatisticsServiceImpl implements DataStatisticsService {
    @Autowired
    private ContractMapper contractMapper;

    @Override
    public byte[] generateChart(DataStatisticsDTO dataStatisticsDTO) throws IOException {
        //计算时间范围
        LocalDateTime[] timeRange = DataChartUtils.calculateDateRange(
                dataStatisticsDTO.getEndTime(),
                dataStatisticsDTO.getStartTime(),
                dataStatisticsDTO.getTimeRange()
        );
        //设置时间范围
        dataStatisticsDTO.setEndTime(timeRange[1]);
        dataStatisticsDTO.setStartTime(timeRange[0]);
        //查询数据
        String title = dataStatisticsDTO.getTitle();
        List<ContractChartDTO> chartData;
        Map<String, Number> resultMap = new LinkedHashMap<>();

        switch (dataStatisticsDTO.getChartType()) {
            case LINE_CHART:
                if (title.equals(ChartTitleConstant.PERFORMANCE)) {
                    chartData = contractMapper.selectPerformanceByPeriod(
                            dataStatisticsDTO.getStartTime(),
                            dataStatisticsDTO.getEndTime(),
                            ContractConstant.SIGN,
                            dataStatisticsDTO.getTimeRange()
                    );
                } else {
                    chartData = contractMapper.selectNumByPeriod(
                            dataStatisticsDTO.getStartTime(),
                            dataStatisticsDTO.getEndTime(),
                            ContractConstant.SIGN,
                            dataStatisticsDTO.getTimeRange()
                    );
                }
                //计算时间间距
                long between = (dataStatisticsDTO.getTimeRange() == TimeRangeOperate.THIS_YEAR)
                        ? ChronoUnit.MONTHS.between(timeRange[0], timeRange[1]) + 1
                        : ChronoUnit.DAYS.between(timeRange[0], timeRange[1]) + 1;
                //判断是否需要补全日期数据
                boolean flag = (chartData.size() == between);
                if (flag) {
                    resultMap = convertListToMap(title, chartData);
                } else {
                    //设置日期格式
                    DateTimeFormatter formatter = (dataStatisticsDTO.getTimeRange() == TimeRangeOperate.THIS_YEAR)
                            ? DateTimeFormatter.ofPattern("yyyy-MM")
                            : DateTimeFormatter.ofPattern("yyyy-MM-dd");

                    Map<String, Number> result = convertListToMap(title, chartData);

                    LocalDateTime currentTime = dataStatisticsDTO.getStartTime();

                    //补全日期
                    while (!currentTime.isAfter(dataStatisticsDTO.getEndTime())) {
                        String dateKey = formatter.format(currentTime);
                        resultMap.put(dateKey, result.getOrDefault(dateKey, 0));
                        //根据类型选择按天或按年递增
                        currentTime = (dataStatisticsDTO.getTimeRange() == TimeRangeOperate.THIS_YEAR)
                                ? currentTime.plusMonths(1)
                                : currentTime.plusDays(1);
                    }
                }
                break;
            case PIE_CHART:
                chartData = contractMapper.selectCompanySourceByPeriod(
                        dataStatisticsDTO.getStartTime(),
                        dataStatisticsDTO.getEndTime(),
                        ContractConstant.SIGN
                );
                resultMap = convertListToMap(title, chartData);
                break;
            default:
                throw new IllegalArgumentException("不支持的图表类型");
        }

        //画表
        JFreeChart chart = DataChartUtils.createChart(
                dataStatisticsDTO.getChartType(),
                dataStatisticsDTO.getTitle(),
                resultMap);
        return convertChartToJpeg(chart);
    }

    /**
     * 将图表转换为JPEG字节数组
     */
    public byte[] convertChartToJpeg(JFreeChart chart) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        // 设置图片尺寸和质量
        ChartUtils.writeChartAsJPEG(outputStream, chart, 800, 600);

        byte[] chartData = outputStream.toByteArray();
        outputStream.close();

        return chartData;
    }

    /**
     * 将List转为Map
     */
    public Map<String, Number> convertListToMap(String title, List<ContractChartDTO> list) {
        if (title.equals(ChartTitleConstant.PERFORMANCE)) {
            return list.stream()
                    .collect(Collectors.toMap(
                            ContractChartDTO::getChartTitle,
                            ContractChartDTO::getPerformance
                    ));
        }
        return list.stream()
                .collect(Collectors.toMap(
                        ContractChartDTO::getChartTitle,
                        ContractChartDTO::getNum
                ));
    }
}
